#!/usr/bin/perl
use strict;
my ($u, $pgm, $compress);

use Getopt::Long;

$pgm = readlink $0;
$pgm and $0 = $pgm;
$pgm = ($0 =~ m!/([^/]+)$!)[0] || $0;
my $setup_version = 1;
GetOptions('u=s'=>\$u, 'setup-version!'=>\$setup_version, 'C'=>\$compress) or do {
    die "usage: $pgm [-u setup-file] [--[no]setup-version] [dir]\n";
};

use FindBin;
use lib "$FindBin::Bin";

use Cygwin::Setup;
use Cygwin::Setup::Listing;
use Cygwin::Setup::ByDir;

my ($initfn, $newfn);
open(STDOUT, ">" . ($newfn = "/tmp/upset.$$")) if $u;
$| = 1;

my $package = new Cygwin::Setup;

$. = 0;
if ($u && open(U, $u)) {
    $initfn = $u;
    while ($package->iniparse ($u, \*U)) {
	next;
    }
}

if ($package->{-error}) {
    print STDERR "upset: $package->{-error}\n";
    exit 1;
}

if ($setup_version) {
    $package->exe_version("setup.exe") or die "couldn't get version from setup.exe - $!\n";
}

if ($package->{-error}) {
    print STDERR "upset: $package->{-error}\n";
    exit 1;
}

@ARGV = ('release') unless @ARGV;
$package->dir_update(@ARGV);

if ($package->{-error}) {
    print STDERR "upset: $package->{-error}\n";
    exit 1;
}

print <<BLAH;
# This file is automatically generated.  If you edit it, your
# edits will be discarded next time the file is generated.
# See http://cygwin.com/setup.html for details.
#
BLAH

# Also updates auto dependencies

$package->update_listing();

my $pkg = $package->{'__setup'}{''};
print "setup-timestamp: ", time, "\n";
print "setup-version: ", $pkg->{'setup-version'}, "\n"
    if $pkg->{'setup-version'};

delete $package->{'__setup'};

for my $p ($package->names) {
    next if defined($package->{$p}{''}{'skip'});
    if ($package->{$p}{_me} ne $p) {
	$p = $package->{$p}{_me};
	next if $package->{$p}{''}{'skip'};
    }

    $pkg = $package->{$p};
    my $pkgbase = $pkg->{''};
    $pkgbase->{'skip'} = 1;
    print "\n@ $p\n";
    if ($pkgbase->{'sdesc'}) {
	$pkgbase->{'sdesc'} =~ s/^("?)[^:]+:\s*/$1/o;
	$pkgbase->{'sdesc'} =~ s/^("?)([a-z])/$1\u$2/o;
	print "sdesc: ", $pkgbase->{'sdesc'}, "\n";
	# delete $pkgbase->{'sdesc'};
    }
    if ($pkgbase->{'ldesc'}) {
	print "ldesc: ", $pkgbase->{'ldesc'}, "\n";
	delete $pkgbase->{'ldesc'};
    }
    if ($pkgbase->{'category'}) {
	print "category:", map(" \u$_", (split(' ', $pkgbase->{'category'}))), "\n";
	delete $pkgbase->{'category'};
    } else {
	print "category: ", 'Misc', "\n";
    }
    if ($pkgbase->{'requires'}) {
	foreach my $r (split(' ', $pkgbase->{'requires'})) {
	    if (!defined($package->{$r})) {
		warn "upset: *** warning package $p requires non-existent package $r\n";
	    }
	}
	print "requires: ", $pkgbase->{'requires'}, "\n";
	delete $pkgbase->{'requires'};
    };
    for my $g ('', 'prev', 'test') {
	my $ver = $pkg->{$g} or next;
	print "[$g]\n" if length($g);
	yup: for my $n ('version', 'install', 'source') {
	    if ($ver->{$n}) {
		print "$n: $ver->{$n}\n";
		next;
	    } elsif ($n ne 'source' || !defined($pkg->{''}{'external-source'})) {
		next;
	    }

	    my $v = $ver->{'version'};
	    defined($v) or next;

	    my $tarpkg = $package->{$pkg->{''}{'external-source'}};
	    my $srcfn = $tarpkg->{_me} . '-' . $v . '-src.tar.bz2';
	    my $srcpath = $package->{-sources}{$srcfn};
	    if (defined($srcpath)) {
		print "$n: $srcpath\n";
	     } else {
		 for my $g1 ('', 'prev', 'test') {
		     if ($tarpkg->{$g1}{'version'} eq $v) {
			 if (!$tarpkg->{$g1}{'source'}) {
			     warn "upset: *** No source file found for $pkg->{''}{'external-source'}-$v\n";
			     next;
			 } else {
			     print "$n: $tarpkg->{$g1}{'source'}\n";
			 }
			next yup;
		     }
		 }
		warn "upset: *** warning package $p refers to non-existent external-source: $pkg->{''}{'external-source'}\n";
	    }
	}
    }
}

if ($u) {
    my $changed = 0;
    open(STDOUT, ">/dev/null");
    system  qw/diff -I^setup-timestamp -w -B -q/, $initfn, $newfn and do {
	system 'mv', $newfn, $initfn;
	$changed = 1;
    };
    if ($compress) {
	my $bz2 = $initfn;
	$bz2 =~ s/\.ini//o;
	$bz2 .= '.bz2';
	exec "exec bzip2 <$initfn >$bz2" if $changed || ! -f $bz2;
    }
    unlink($newfn);
}
exit(0);
